package com.fpt.quanlyhethongsan.controller;

import java.io.ByteArrayOutputStream;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;

import com.fpt.quanlyhethongsan.utils.Constants;
import com.fpt.quanlyhethongsan.utils.EnglishNumberToWords;
import com.fpt.quanlyhethongsan.utils.UserRole;
import com.fpt.quanlysanbong.dao.ServiceDao;
import com.fpt.quanlysanbong.dao.ServiceOrderDao;
import com.fpt.quanlysanbong.dao.SoccerFieldDao;
import com.fpt.quanlysanbong.dao.SoccerOrderDao;
import com.fpt.quanlysanbong.domain.Account;
import com.fpt.quanlysanbong.domain.ServiceOrder;
import com.fpt.quanlysanbong.domain.SoccerField;
import com.fpt.quanlysanbong.domain.SoccerOrder;
import com.fpt.quanlysanbong.domain.SoccerService;
import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.pdf.BaseFont;
import com.lowagie.text.pdf.PdfPTable;
import com.lowagie.text.pdf.PdfWriter;

public class ServiceOrderController {
	private int id;
	private int orderId;
	private int serviceId;
	private float unitPrice;
	private int number_items;
	private List<SoccerOrder> listSoccerOrder;
	private String keyword;
	private List<ServiceOrder> listServiceOrder;
	private List<SoccerService> listSoccerService;
	private String operation;
	private SoccerOrder soccerOrder;
	private float totalServiceOrder;
	private float total;
	private int soccerFieldId;
	private List<SoccerField> listSoccerField;
	private String tu_ngay;
	private String toi_ngay;
	private float totalSoccerOrder;

	public float getTotalSoccerOrder() {
		return totalSoccerOrder;
	}

	public void setTotalSoccerOrder(float totalSoccerOrder) {
		this.totalSoccerOrder = totalSoccerOrder;
	}

	public String getTu_ngay() {
		return tu_ngay;
	}

	public void setTu_ngay(String tu_ngay) {
		this.tu_ngay = tu_ngay;
	}

	public String getToi_ngay() {
		return toi_ngay;
	}

	public void setToi_ngay(String toi_ngay) {
		this.toi_ngay = toi_ngay;
	}

	public List<SoccerField> getListSoccerField() {
		return listSoccerField;
	}

	public void setListSoccerField(List<SoccerField> listSoccerField) {
		this.listSoccerField = listSoccerField;
	}

	public int getSoccerFieldId() {
		return soccerFieldId;
	}

	public void setSoccerFieldId(int soccerFieldId) {
		this.soccerFieldId = soccerFieldId;
	}

	public float getTotalServiceOrder() {
		return totalServiceOrder;
	}

	public void setTotalServiceOrder(float totalServiceOrder) {
		this.totalServiceOrder = totalServiceOrder;
	}

	public float getTotal() {
		return total;
	}

	public void setTotal(float total) {
		this.total = total;
	}

	public SoccerOrder getSoccerOrder() {
		return soccerOrder;
	}

	public void setSoccerOrder(SoccerOrder soccerOrder) {
		this.soccerOrder = soccerOrder;
	}

	public String getOperation() {
		return operation;
	}

	public void setOperation(String operation) {
		this.operation = operation;
	}

	public List<SoccerService> getListSoccerService() {
		return listSoccerService;
	}

	public void setListSoccerService(List<SoccerService> listSoccerService) {
		this.listSoccerService = listSoccerService;
	}

	public List<ServiceOrder> getListServiceOrder() {
		return listServiceOrder;
	}

	public void setListServiceOrder(List<ServiceOrder> listServiceOrder) {
		this.listServiceOrder = listServiceOrder;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public int getOrderId() {
		return orderId;
	}

	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}

	public int getServiceId() {
		return serviceId;
	}

	public void setServiceId(int serviceId) {
		this.serviceId = serviceId;
	}

	public float getUnitPrice() {
		return unitPrice;
	}

	public void setUnitPrice(float unitPrice) {
		this.unitPrice = unitPrice;
	}

	public int getNumber_items() {
		return number_items;
	}

	public void setNumber_items(int number_items) {
		this.number_items = number_items;
	}

	public List<SoccerOrder> getListSoccerOrder() {
		return listSoccerOrder;
	}

	public void setListSoccerOrder(List<SoccerOrder> listSoccerOrder) {
		this.listSoccerOrder = listSoccerOrder;
	}

	public String getKeyword() {
		return keyword;
	}

	public void setKeyword(String keyword) {
		this.keyword = keyword;
	}

	public String searchSoccerOrder() {
		HttpSession session = ServletActionContext.getRequest().getSession();
		if (session.getAttribute(Constants.USER_SESSION) == null)
			return Constants.ERROR;
		SoccerField soccerField = (SoccerField) session.getAttribute(Constants.CURRENT_FIELD);

		listSoccerOrder = new SoccerOrderDao().getListOrderByKeyWord(keyword, soccerField.getId());

		return Constants.SUCCESS;
	}

	public String getListServiceOrders() {
		HttpSession session = ServletActionContext.getRequest().getSession();
		if (session.getAttribute(Constants.USER_SESSION) == null)
			return Constants.ERROR;
		SoccerField soccerField = (SoccerField) session.getAttribute(Constants.CURRENT_FIELD);
		if (orderId != 0) {
			session.setAttribute(Constants.CURRENT_SOCCER_ORDER, orderId);
		} else {
			orderId = (Integer) session.getAttribute(Constants.CURRENT_SOCCER_ORDER);
		}

		listServiceOrder = new ServiceOrderDao().getListServiceOrder(orderId);
		listSoccerService = new ServiceDao().getListService(soccerField.getId());
		soccerOrder = new SoccerOrderDao().getSoccerOrder(orderId);

		setOperation(Constants.UPDATE);
		return Constants.SUCCESS;
	}

	public String getFormatDate(Date date) {
		SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");
		if (date == null)
			date = new Date();
		return f.format(date.getTime());
	}

	public String saveServiceOrder() {

		HttpSession session = ServletActionContext.getRequest().getSession();
		if (session.getAttribute(Constants.USER_SESSION) == null)
			return Constants.ERROR;
		orderId = (Integer) session.getAttribute(Constants.CURRENT_SOCCER_ORDER);

		ServiceOrder so = new ServiceOrder();

		so.setUnitPrice(unitPrice);
		so.setNumber_items(number_items);
		so.setService(new SoccerService());
		so.getService().setId(serviceId);
		so.setOrderId(new SoccerOrder());
		so.getOrderId().setId(orderId);

		if (StringUtils.equalsIgnoreCase(operation, Constants.ADD)) {
			new ServiceOrderDao().addService(so);
		} else if (StringUtils.equalsIgnoreCase(operation, Constants.UPDATE)) {
			so.setId(id);
			new ServiceOrderDao().editService(so);
		}

		return Constants.SUCCESS;
	}

	public String addServiceOrder() {
		HttpSession session = ServletActionContext.getRequest().getSession();
		if (session.getAttribute(Constants.USER_SESSION) == null)
			return Constants.ERROR;
		SoccerField soccerField = (SoccerField) session.getAttribute(Constants.CURRENT_FIELD);
		
		orderId = (Integer) session.getAttribute(Constants.CURRENT_SOCCER_ORDER);

		listSoccerService = new ServiceDao().getListService(soccerField.getId());
		soccerOrder = new SoccerOrderDao().getSoccerOrder(orderId);
		setOperation(Constants.ADD);
		return Constants.SUCCESS;
	}

	public String getPriceFormat(float number) {
		DecimalFormat f = new DecimalFormat("#,###,###");
		return f.format(number);
	}

	public String getPrice(float number) {
		DecimalFormat f = new DecimalFormat("###");
		return f.format(number);
	}

	public String getDateFormat(Date date) {
		SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyy");
		if (date == null) {
			date = new Date();
		}
		return f.format(date.getTime());
	}

	public String deleteServiceOrder() {
		HttpSession session = ServletActionContext.getRequest().getSession();
		if (session.getAttribute(Constants.USER_SESSION) == null)
			return Constants.ERROR;
		new ServiceOrderDao().deleteService(id);
		return Constants.SUCCESS;
	}

	public String printBill() {
		HttpSession session = ServletActionContext.getRequest().getSession();
		if (session.getAttribute(Constants.USER_SESSION) == null)
			return Constants.ERROR;
		SoccerField soccerField = (SoccerField) session.getAttribute(Constants.CURRENT_FIELD);

		listSoccerOrder = new SoccerOrderDao().getListOrderByKeyWord(keyword, soccerField.getId());
		listServiceOrder = new ServiceOrderDao().getListServiceOrder(orderId);
		soccerOrder = new SoccerOrderDao().getSoccerOrder(orderId);

		for (ServiceOrder so : listServiceOrder) {
			totalServiceOrder += (so.getUnitPrice() * so.getNumber_items());
		}

		if (soccerOrder != null) {
			total = totalServiceOrder + soccerOrder.getTimeDivision().getPrice();
		}

		return Constants.SUCCESS;
	}

	public String getWordsOfNumber(float number) {
		int no = Math.round(number);
		return EnglishNumberToWords.convert(no);
	}

	// print pdf file
	public void printBillPdf() {
		HttpSession session = ServletActionContext.getRequest().getSession();
		Account currentUser = (Account) session.getAttribute(Constants.USER_SESSION);

		listServiceOrder = new ServiceOrderDao().getListServiceOrder(orderId);
		soccerOrder = new SoccerOrderDao().getSoccerOrder(orderId);

		for (ServiceOrder so : listServiceOrder) {
			totalServiceOrder += (so.getUnitPrice() * so.getNumber_items());
		}

		if (soccerOrder != null) {
			total = totalServiceOrder + soccerOrder.getTimeDivision().getPrice();
		}

		try {
			HttpServletResponse response = ServletActionContext.getResponse();
			Document doc = new Document();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			PdfWriter.getInstance(doc, baos);
			doc.open();

			// noi dung bao cao
			final String FONT = "arialbd.ttf";
			// define font for table header row
			BaseFont vnFont = BaseFont.createFont(FONT, BaseFont.IDENTITY_H, BaseFont.EMBEDDED);
			Font font = new Font(vnFont, 13f, Font.NORMAL);

			Paragraph header = new Paragraph("Thông tin hóa đơn", font);
			header.setAlignment(Paragraph.ALIGN_CENTER);
			doc.add(header);

			Paragraph space = new Paragraph("", font);
			doc.add(space);
			doc.add(space);

			font.setSize(9f);

			PdfPTable table = new PdfPTable(2);
			table.setWidthPercentage(100.0f);
			table.setWidths(new float[] { 2.5f, 7.5f });
			table.setSpacingBefore(10);

			// write table row data
			table.addCell(new Phrase("Ngày thanh toán", font));
			table.addCell(new Phrase(getFormatDate(null), font));

			table.addCell(new Phrase("Mã hóa đơn", font));
			table.addCell(new Phrase(soccerOrder.getOrderNo(), font));

			table.addCell(new Phrase("Tên khách hàng", font));
			table.addCell(new Phrase(soccerOrder.getPerson().getName(), font));

			table.addCell(new Phrase("Điện thoại", font));
			table.addCell(new Phrase(soccerOrder.getPerson().getPhone(), font));

			table.addCell(new Phrase("Email", font));
			table.addCell(new Phrase(soccerOrder.getPerson().getEmail(), font));

			table.addCell(new Phrase("Địa chỉ", font));
			table.addCell(new Phrase(soccerOrder.getPerson().getAddress(), font));

			table.addCell(new Phrase("Ngày bắt đầu", font));
			table.addCell(new Phrase(getFormatDate(soccerOrder.getStartDate()), font));

			table.addCell(new Phrase("Ngày kết thúc", font));
			table.addCell(new Phrase(getFormatDate(soccerOrder.getEndDate()), font));

			table.addCell(new Phrase("Khung giờ", font));
			table.addCell(new Phrase(soccerOrder.getTimeDivision().getPeriod(), font));

			table.addCell(new Phrase("Giá thuê sân(VND)", font));
			table.addCell(new Phrase(getPriceFormat(soccerOrder.getTimeDivision().getPrice()), font));

			table.addCell(new Phrase("Dịch vụ khác: ", font));
			table.addCell(StringUtils.EMPTY);
			// service table
			PdfPTable tableService = new PdfPTable(4);
			tableService.setWidthPercentage(100.0f);
			tableService.setWidths(new float[] { 2.5f, 2.5f, 2.5f, 2.5f });
			tableService.setSpacingBefore(10);

			tableService.addCell(new Phrase("Tên dịch vụ", font));
			tableService.addCell(new Phrase("Đơn giá(VND)", font));
			tableService.addCell(new Phrase("Số lượng", font));
			tableService.addCell(new Phrase("Tổng tiền(VND)", font));

			for (ServiceOrder so : listServiceOrder) {
				tableService.addCell(new Phrase(so.getService().getName(), font));
				tableService.addCell(new Phrase(getPriceFormat(so.getUnitPrice()), font));
				tableService.addCell(new Phrase(String.valueOf(so.getNumber_items()), font));
				tableService.addCell(new Phrase(getPriceFormat(so.getUnitPrice() * so.getNumber_items()), font));
			}
			tableService.addCell(new Phrase(StringUtils.EMPTY, font));
			tableService.addCell(new Phrase(StringUtils.EMPTY, font));
			tableService.addCell(new Phrase(StringUtils.EMPTY, font));
			tableService.addCell(new Phrase(getPriceFormat(totalServiceOrder), font));
			// end service table
			table.addCell(StringUtils.EMPTY);
			table.addCell(tableService);

			table.addCell(new Phrase("Tổng tiền (VND)", font));
			table.addCell(new Phrase(getPriceFormat(total), font));
			
			table.addCell(new Phrase("Đặt cọc (VND)", font));
			table.addCell(new Phrase(getPriceFormat(soccerOrder.getDeposits()), font));
			
			table.addCell(new Phrase("Cần thanh toán (VND)", font));
			table.addCell(new Phrase(getPriceFormat(total - soccerOrder.getDeposits()), font));

			table.addCell(new Phrase("Bằng chữ", font));
			table.addCell(new Phrase(EnglishNumberToWords.convert(Math.round(total - soccerOrder.getDeposits())), font));

			doc.add(table);

			// người làm báo cáo
			doc.add(space);
			doc.add(space);

			Calendar cal = Calendar.getInstance();
			int year = cal.get(Calendar.YEAR);
			int month = cal.get(Calendar.MONTH) + 1;
			int day = cal.get(Calendar.DAY_OF_MONTH);

			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.append("Hà Nội, ngày ");
			stringBuilder.append(day);
			stringBuilder.append(" tháng ");
			stringBuilder.append(month);
			stringBuilder.append(" năm ");
			stringBuilder.append(year);
			Paragraph hanoi = new Paragraph(stringBuilder.toString(), font);
			hanoi.setAlignment(Paragraph.ALIGN_RIGHT);
			Paragraph nguoi_bao_cao = new Paragraph("Người làm hóa đơn", font);
			nguoi_bao_cao.setAlignment(Paragraph.ALIGN_RIGHT);

			Paragraph ky_ten = new Paragraph(currentUser.getPerson().getName(), font);
			ky_ten.setAlignment(Paragraph.ALIGN_RIGHT);

			doc.add(hanoi);
			doc.add(nguoi_bao_cao);
			doc.add(ky_ten);

			doc.close();
			ServletOutputStream outputStream = response.getOutputStream();
			baos.writeTo(outputStream);
			response.setHeader("Content-Disposition", "attachment; filename=\"hoa_don.pdf\"");
			response.setContentType("application/pdf");
			outputStream.flush();
			outputStream.close();
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	public String getBillHistory() {
		HttpSession session = ServletActionContext.getRequest().getSession();
		if (session.getAttribute(Constants.USER_SESSION) == null)
			return Constants.ERROR;
		Account acc = (Account) session.getAttribute(Constants.USER_SESSION);
		listSoccerField = new ArrayList<SoccerField>();
		listSoccerOrder = new ArrayList<SoccerOrder>();

		if (acc.getRole().getId() == UserRole.STAFF.getId()) {
			SoccerField soccerField = (SoccerField) session.getAttribute(Constants.CURRENT_FIELD);
			listSoccerField.add(soccerField);
			listSoccerOrder = new SoccerOrderDao().getListOrderByDate(tu_ngay, toi_ngay, soccerFieldId);
		} else {
			listSoccerField = new SoccerFieldDao().getListSoccerField(acc.getPerson().getId());
			if (soccerFieldId == 0) {
				for (SoccerField sf : listSoccerField) {
					listSoccerOrder.addAll(new SoccerOrderDao().getListOrderByDate(tu_ngay, toi_ngay, sf.getId()));
				}
			} else {
				listSoccerOrder.addAll(new SoccerOrderDao().getListOrderByDate(tu_ngay, toi_ngay, soccerFieldId));
			}
		}

		listServiceOrder = new ServiceOrderDao().getListHistoryServiceOrder(toi_ngay, orderId);
		soccerOrder = new SoccerOrderDao().getSoccerOrder(orderId);

		if (soccerOrder != null) {
			try {
				long diff = (24 * 60 * 60 * 1000);
				for (ServiceOrder so : listServiceOrder) {
					totalServiceOrder += (so.getUnitPrice() * so.getNumber_items());
				}

				SimpleDateFormat f = new SimpleDateFormat("dd/MM/yyyyy");

				Date to = f.parse(toi_ngay);

				if (soccerOrder.getCancel_date() == null || soccerOrder.getCancel_date().after(to)) {
					if (to.after(soccerOrder.getEndDate())) {
						diff += soccerOrder.getEndDate().getTime() - soccerOrder.getStartDate().getTime();
					} else {
						diff += to.getTime() - soccerOrder.getStartDate().getTime();
					}
				} else {
					diff = soccerOrder.getCancel_date().getTime() - soccerOrder.getStartDate().getTime();
				}

				long diffDays = diff / (24 * 60 * 60 * 1000);
				totalSoccerOrder = diffDays * soccerOrder.getTimeDivision().getPrice();
				total += (totalServiceOrder + totalSoccerOrder);
			} catch (ParseException e) {
				e.printStackTrace();
			}
		}

		return Constants.SUCCESS;
	}
	
	public boolean checkAddService(Date endDate) {
		boolean check = false;
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		Date currentDate = new Date();
		if(sdf.format(endDate).compareTo(sdf.format(currentDate)) >= 0){
				check = true;
		}
		return check;
	}
}
